#include "OclLapack.h"
#include "clAmdBlas.h"
#include "../clUtils.h"
#include "../AmdConvertEnum.h"
#include "../ClMem.h"
#include <cmath>

using namespace std;

void OclLapack::sgemv(char *trans, int m, int n, float alpha, 
		const cl_ptr a, int lda,
		const cl_ptr x, int incX,
		float beta,
		cl_ptr y, int incY) 
{	
	Measure measure("sgemv-ocl");
	
	cl_event event;
    CL_CHECK(clAmdBlasSgemvEx(
        clAmdBlasColumnMajor, toAmdTrans(trans),
        m, n, alpha,
        a.handle, a.offset, lda,
        x.handle, x.offset, incX, 
		beta,
        y.handle, y.offset, incY, 
        1, &queue, 
        0, NULL,
        &event));
	
	ClEvent(event).wait();
}

int OclLapack::sgemv(char *trans, int *m, int *n, float *alpha, 
	float *a, int *lda, float *x, int *incx, float *beta, float *y, 
	int *incy) 
{
	bool isTranspose = (tolower(trans[0]) == 't');
    size_t sizeX = isTranspose ? *m : *n;
    size_t sizeY = isTranspose ? *n : *m;
    size_t countY = 1 + (sizeY - 1) * abs(*incy);
	
	ClMem<float> memA(queue, (*lda) * (*n), a);
	ClMem<float> memX(queue, 1 + (sizeX - 1) * abs(*incx), x);
	ClMem<float> memY(queue, countY, y);

	sgemv(trans, *m, *n, *alpha,
		cl_ptr(memA), *lda,
        cl_ptr(memX), *incx, 
		*beta,
        cl_ptr(memY), *incy);

    memY.beginRead(y, 0, countY).wait();
	
    return 0;
}
